package cn.semcorp.zhuhaizj.exception.handler;


import cn.semcorp.zhuhaizj.exception.ServiceException;
import cn.semcorp.zhuhaizj.restful.JsonResult;
import cn.semcorp.zhuhaizj.restful.ResponseCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.messaging.handler.annotation.support.MethodArgumentTypeMismatchException;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

import javax.validation.ConstraintViolationException;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.SQLException;
import java.time.format.DateTimeParseException;
import java.util.NoSuchElementException;
import java.util.concurrent.TimeoutException;

/**
 * 全局异常处理器
 */
@RestControllerAdvice
@Slf4j
public class GlobalControllerException {

    /**
     * 处理业务异常
     */
    @ExceptionHandler(value = ServiceException.class)
    public JsonResult handleServiceException(ServiceException e) {
        return JsonResult.failed("异常类型 : ServiceException.Class, 异常原因: "+ e.getMessage());
    }

    @ExceptionHandler(value = SQLException.class)
    public JsonResult handleSQLException(SQLException e) {
        return JsonResult.failed("异常类型 : SQLException.Class, 异常原因: "+ e.getMessage());
    }

    @ExceptionHandler(value = RuntimeException.class)
    public JsonResult handleException(RuntimeException e) {
        return JsonResult.failed("异常类型 : RuntimeException.Class, 异常原因: "+ e.getMessage());
    }




    /**
     * 处理绑定异常（通过Validation框架验证请求参数时的异常）
     */
    @ExceptionHandler(value = BindException.class)
    public JsonResult handleBindException(BindException e) {
        return JsonResult.failed("异常类型 : BindException.Class, 异常原因: Validate验证失败或"+ e.getMessage());

    }


    @ExceptionHandler(value = ConstraintViolationException.class)
    public JsonResult handleConstraintViolationException(ConstraintViolationException e) {
        return JsonResult.failed("尝试保存或更新实体对象到数据库，对象的属性违反了定义在实体类上的验证约束,请检查重试!",e.getMessage());
    }

    @ExceptionHandler(value = DateTimeParseException.class)
    public JsonResult handleDateTimeParseException(DateTimeParseException e) {
        return JsonResult.failed("时间转换格式失败,请检查重试!",e.getMessage());
    }



    @ExceptionHandler(value = NullPointerException.class)
    public JsonResult handleNullPointerException(NullPointerException e) {
        return JsonResult.failed("无法调用尚未初始化的对象引用（空指针）",e.getMessage());
    }

    @ExceptionHandler(value = ArrayIndexOutOfBoundsException.class)
    public JsonResult handleArrayIndexOutOfBoundsException(ArrayIndexOutOfBoundsException e) {
        return JsonResult.failed("无法访问数组中不存在的索引,超出数组的最大长度",e.getMessage());

    }

    @ExceptionHandler(value = ClassCastException.class)
    public JsonResult handleClassCastException(ClassCastException e) {
        return JsonResult.failed("对象强制转换为不兼容的类型",e.getMessage());
    }

    @ExceptionHandler(value = ArithmeticException.class)
    public JsonResult handleArithmeticException(ArithmeticException e) {
        return JsonResult.failed("算术运算执行中断,遇不可计算值",e.getMessage());
    }

    @ExceptionHandler(value = IllegalArgumentException.class)
    public JsonResult handleIllegalArgumentException(IllegalArgumentException e) {
        return JsonResult.failed("方法接收到无效参数",e.getMessage());
    }

    @ExceptionHandler(value = IOException.class)
    public JsonResult handleIOException(IOException e) {
        return JsonResult.failed("输入/输出操作出现异常",e.getMessage());
    }



    @ExceptionHandler(value = NoSuchElementException.class)
    public JsonResult handleNoSuchElementException(NoSuchElementException e) {
        return JsonResult.failed("迭代器没有更多的元素可返回",e.getMessage());
    }

    @ExceptionHandler(value = IndexOutOfBoundsException.class)
    public JsonResult handleIndexOutOfBoundsException(IndexOutOfBoundsException e) {
        return JsonResult.failed("访问集合或数组的索引越界",e.getMessage());
    }

    @ExceptionHandler(value = SecurityException.class)
    public JsonResult handleSecurityException(SecurityException e) {
        return JsonResult.failed("安全策略(权限)阻止了操作或无权限操作",e.getMessage());
    }

    @ExceptionHandler(value = TimeoutException.class)
    public JsonResult handleTimeoutException(TimeoutException e) {
        return JsonResult.failed("网络请求等待时间过长或操作超时",e.getMessage());
    }
    @ExceptionHandler(value = NumberFormatException.class)
    public JsonResult handleNumberFormatException(NumberFormatException e) {
        return JsonResult.failed("字符串转换为数字类型失败",e.getMessage());
    }
    @ExceptionHandler(value = OutOfMemoryError.class)
    public JsonResult handleOutOfMemoryError(OutOfMemoryError e) {
        return JsonResult.failed("可用内存不足,内存泄漏或分配了过多的对象",e.getMessage());
    }


    /**
     * 处理系统（其它）异常
     */
    @ExceptionHandler(value = Throwable.class)
    public JsonResult handleSystemError(Throwable e) {
//        log.info("出现系统异常，异常类型={}，描述文本={}", e.getClass().getName(), e.getMessage());
//        e.printStackTrace();
//        String message = e.getMessage();
//        JsonResult result = JsonResult.failed(ResponseCode.INTERNAL_SERVER_ERROR, message);
//        log.info("即将返回：{}", result);
        return JsonResult.failed("出现其他错误,兜底捕获,请联系开发解决!",e.getMessage());
    }
}
